/*
 ============================================================================
 Name		: EngineManager.cpp
 Author	  : JohnLZeng
 Version	 : 1.0
 Copyright   : Your copyright notice
 Description : CEngineManager implementation
 ============================================================================
 */

#include "EngineManager.h"
#include "SHPlatform.h"
#include "MacroUtil.h"
#include "DocListEngine.h"
#include "DownloadEngine.h"
#include "FileManagerUtil.h"
#include "RSSXmlParser.h"

#include "QWString.h"
#include "cx_moduleinterface.h"
#include "QQReaderMessageId.h"
#include "QQReaderModuleId.h"
#include "cx_string.h"
#include "QQReaderStatusDef.h"

CEngineManager::CEngineManager() :
	iParseEvent(NULL),iDownloadProcessNotify(NULL)
	{
	// No implementation required
	}

CEngineManager::~CEngineManager()
	{
		SAFE_DELETE(iDocListEngine)
		SAFE_DELETE(iDownloadEngine)
		SAFE_DELETE(iXmlParser)
	}

CEngineManager* CEngineManager::NewLC()
	{
	CEngineManager* self = new (ELeave) CEngineManager();
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

CEngineManager* CEngineManager::NewL()
	{
	CEngineManager* self = CEngineManager::NewLC();
	CleanupStack::Pop(); // self;
	return self;
	}

void CEngineManager::ConstructL()
	{
	iDocListEngine = CDocListEngine::NewL();
	iDownloadEngine = CDownloadEngine::NewL();
	iXmlParser = CRSSXmlParser::NewL();
	iXmlParser->SetParseNotify(this);
	}

void CEngineManager::Init()
	{
	if (iDocListEngine)
		iDocListEngine->Init();
	if (iDownloadEngine)
		iDownloadEngine->Init();

	MQHttpNotifier* httpNotifier = (MQHttpNotifier*) (this);
	cx_sendmessage(EMessage_BookCity_Browse_SetNotifier,
			(unsigned int) httpNotifier, 0, EModule_Controller_BookCity, -1);

	MQDownloadNotifier* downloadNotifier = (MQDownloadNotifier*) this;
	cx_sendmessage(EMessage_BookCity_Download_SetDownloadNotifier,
			(unsigned int) downloadNotifier, 0, EModule_Controller_BookCity, -1);
	
	
	ArrayDocList* list = SHModel()->GetDocList();
	iDocListEngine->GetByState(*list);
	
	ArrayDownloadList* downnlist = SHModel()->GetDownloadList();
	iDownloadEngine->GetAll(*downnlist);
	}

void CEngineManager::Release()
	{
	cx_sendmessage(EMessage_BookCity_Browse_CancelRequest, 0, 0,
			EModule_Controller_BookCity, -1);
	if (iDocListEngine)
		iDocListEngine->Release();
	if (iDownloadEngine)
		iDownloadEngine->Release();
	}

void CEngineManager::InitParseData()
	{
	ArrayDocList* list = SHModel()->GetDocList();
	iParseInitData.iInsertPos = list->Count();
	ArrayDownloadList* downloadList = SHModel()->GetDownloadList();
	iParseInitData.iInsertDownloadPos = downloadList->Count();
	iParseInitData.iUpdateItems = 0;
	}

void CEngineManager::LoadAllToRSSBriefList(CDesCArray* aDesC)
	{
	ArrayDocList* list = SHModel()->GetDocList();
	iDocListEngine->GetAll(*list);
	iDocListEngine->ConvertToListFormat(*list, aDesC);
	}

void CEngineManager::LoadToRSSBriefListByState(CDesCArray* aDesC)
	{
	ArrayDocList* list = SHModel()->GetDocList();
	iDocListEngine->GetByState(*list);
	iDocListEngine->ConvertToListFormat(*list, aDesC);
	}

void CEngineManager::ReloadRSSBriefList()
	{
	ArrayDocList* list = SHModel()->GetDocList();
	list->ResetAndDestroy();
	iDocListEngine->GetByState(*list);
	}

void CEngineManager::UpdateAllToRSSBriefList(CDesCArray* aDesC)
	{
	ArrayDocList* list = SHModel()->GetDocList();
	iDocListEngine->ConvertToListFormat(*list, aDesC);
	}

TInt CEngineManager::AddToRssBriefList(const TDesC& aItem, TDes& aFormat)
	{
	ArrayDocList* list = SHModel()->GetDocList();
	CRSSBriefData* item = iDocListEngine->AppendToList(*list, aItem);
	iDocListEngine->ConvertToListFormat(item, aFormat);
	return KErrNone;
	}

TInt CEngineManager::ConvertToBriefListIndex(const TInt& aPos)
	{
	ArrayDocList* list = SHModel()->GetDocList();
	TInt count = list->Count();
	TInt index = -1;
	if (aPos >= 0 && count > aPos)
		index = count - 1 - aPos;
	return index;
	}

void CEngineManager::RemoveFromRssBriefList(const TInt& aPos)
	{
	TInt index = ConvertToBriefListIndex(aPos);
	ArrayDocList* list = SHModel()->GetDocList();
	if (index >= 0)
		{
		iDocListEngine->RemoveFromList(*list, index);
		}
	}

void CEngineManager::ReadFromRssBriefList(const TInt& aPos)
	{
	TInt index = ConvertToBriefListIndex(aPos);
	ArrayDocList* list = SHModel()->GetDocList();
	if (index >= 0)
		{
		CRSSBriefData* item = (*list)[index];
		item->SetReadState(CRSSBriefData::EDocListReaded);
		item->SetUpdate(ETrue);
		iDocListEngine->Save(*list);

		SHModel()->SetDocIndex(index);
		}
	}

TBool CEngineManager::RemoveFromRssBriefList(const TInt& aPos,
		CDesCArray* aArray)
	{
	TInt index = ConvertToBriefListIndex(aPos);
	ArrayDocList* list = SHModel()->GetDocList();
	if (index >= 0)
		{
		iDocListEngine->RemoveFromList(*list, index);
		}
	iDocListEngine->ConvertToListFormat(*list, aArray);
	return EFalse;
	}

TBool CEngineManager::SetReadedToRssBriefList(const TInt& aPos,
		CDesCArray* aArray)
	{
	TInt index = ConvertToBriefListIndex(aPos);
	ArrayDocList* list = SHModel()->GetDocList();
	if (index >= 0)
		{
		CRSSBriefData* item = (*list)[index];
		item->SetReadState(CRSSBriefData::EDocListReaded);
		item->SetUpdate(ETrue);
		iDocListEngine->Save(*list);
		}
	iDocListEngine->ConvertToListFormat(*list, aArray);
	return EFalse;
	}
TBool CEngineManager::SetUnreadToRssBriefList(const TInt& aPos,
		CDesCArray* aArray)
	{
	TInt index = ConvertToBriefListIndex(aPos);
	ArrayDocList* list = SHModel()->GetDocList();
	if (index >= 0)
		{
		CRSSBriefData* item = (*list)[index];
		item->SetReadState(CRSSBriefData::EDocListUnread);
		item->SetUpdate(ETrue);
		iDocListEngine->Save(*list);
		}
	iDocListEngine->ConvertToListFormat(*list, aArray);
	return EFalse;
	}

void CEngineManager::ScanLocal(CDesCArray* aArray)
	{
	SHModel()->SetScanType(CSHModel::EScanTypeLocal);

	iListDesArray = aArray;

	InitParseData();

	TFileName path;
	path.Append(KRssBriefFileLocalPath);
	CDesCArray * fileArray;
	fileArray = new (ELeave) CDesCArrayFlat(5);

	FileManagerUtil::ScanForPostfix(path, KRssBriefFilePostfix, *fileArray);
	for (TInt i = 0; i < fileArray->Count(); i++)
		{
		TPtrC16 file = (*fileArray)[i];
		iXmlParser->ParseFile(file);
		}

	fileArray->Reset();
	delete fileArray;
	}

void CEngineManager::ParseOneItem(CRSSBriefData* aItem)
	{
	ArrayDocList* list = SHModel()->GetDocList();
	//	TInt err = iDocListEngine->Save(*list, aItem);
	TInt err = iDocListEngine->Add(*list, iParseInitData.iInsertPos, aItem);

	if (err == KErrNone)
		{
		if (SHModel()->GetScanType() == CSHModel::EScanTypeOnline)
			{
			iParseInitData.iUpdateItems++;

			TPtrC ptr = aItem->GetMp3Url()->Des();
			ArrayDownloadList* downloads = SHModel()->GetDownloadList();
			//			iDownloadEngine->AddTask(*downloads, ptr);
			iDownloadEngine->AddTask(*downloads,
					iParseInitData.iInsertDownloadPos, ptr);
			}
		}
	}

void CEngineManager::RequestOnline(CDesCArray* aArray)
	{
	SHModel()->SetScanType(CSHModel::EScanTypeOnline);

	iListDesArray = aArray;

	InitParseData();

	CQWString url;
	url.SetData((LPCWSTR) (KRssBriefUrl().Ptr()), KRssBriefUrl().Length());// for browser lean added 091119
	CQWString property, value;
	CQBookCityRequest request(url, property, value, 0);
	cx_sendmessage(EMessage_BookCity_Browse_Request, (unsigned int) (&request),
			0, EModule_Controller_BookCity, -1);
	//	cx_sendmessage(EMessage_BookCity_Browse_Download,(unsigned int)(&url),0,EModule_Controller_BookCity,-1);
	}

void CEngineManager::HandleHttpEvent(TInt aStatus, void* aData)
	{
	QINT aNewStatus = aStatus;
	switch (aStatus)
		{
		case HTTP_EVENT_CONNECTING:
		case HTTP_EVENT_CONNECTED:
		case HTTP_EVENT_SOCKET_DATA:
		case HTTP_EVENT_GET_END:
		case HTTP_EVENT_REDIRECT:
		case HTTP_EVENT_GET_HEAD:
		case HTTP_EVENT_GET_BODY:
		case HTTP_EVENT_GET_PACK_DATA:
		case HTTP_EVENT_HOST_ERR:
		case HTTP_EVENT_CONNECT_ERR:
		case HTTP_EVENT_HTTP_ERR:
		case HTTP_EVENT_SOCKET_ERR:
		case HTTP_EVENT_DATA_ERR:
		case HTTP_EVENT_ERR:
		case HTTP_EVENT_TIMEOUT:
		case HTTP_EVENT_IAP_OPEN_ERR:
		case HTTP_EVENT_TRYRECONNECT_ERR:
			break;
		case HTTP_EVENT_SOCKET_END:
			AfterReceivedData(aData);
			break;
		}
	}

void CEngineManager::AfterReceivedData(void* aData)
	{
	TPtrC8 xml = *(TPtrC8*) aData;
	iXmlParser->Parse(xml);

	ArrayDocList* docList = SHModel()->GetDocList();
	iDocListEngine->Save(*docList);
	iListDesArray->Reset();
	iDocListEngine->ConvertToListFormat(*docList, iListDesArray);

	ArrayDownloadList* list = SHModel()->GetDownloadList();
	iDownloadEngine->Save(*list);
//	iDownloadEngine->StartAll(*list);

	if (iParseEvent)
		iParseEvent->ParseEvent(EParseEventSuccess,
				(void*) &(iParseInitData.iUpdateItems));
	}

void CEngineManager::HandleDownloadStatus(CQWString& filename, CQWString& url,
		QINT aStatus, void* aData)
	{
	switch (aStatus)
		{
		case download_task_finish:
			AfterTaskDone(filename,url);
			break;
		case download_task_downing:
		case download_task_pause:
		case download_task_waiting:
			ChangeTaskStatus(filename,aStatus);
			break;
		}
	}

void CEngineManager::ChangeTaskStatus(CQWString& filename,TInt aStatus)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();
	CDownloadInfoData* info = GetTaskByName(filename);
	if (info)
		{
		info->SetUpdate(ETrue);
		if (aStatus == download_task_downing)
			info->SetState(CDownloadInfoData::EDownloadStateRunning);
		else if (aStatus == download_task_pause)
			info->SetState(CDownloadInfoData::EDownloadStateStop);
		else if (aStatus == download_task_waiting)
			info->SetState(CDownloadInfoData::EDownloadStateWaiting);
//		iDownloadEngine->Save(*list);
		
		UpdateDownloadListView();
		}
	}

void CEngineManager::AfterTaskDone(CQWString& filename,CQWString& url)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();
	TInt index = GetTaskIndexByName(filename);
	if (index != KErrNotFound)
		iDownloadEngine->RemoveCompeleteTask(*list,index);
	
	ArrayDocList* docList = SHModel()->GetDocList();
	index = GetDocIndexByUrl(url);
	if (index != KErrNotFound)
		{
		CRSSBriefData* doc = (*docList)[index];
		doc->SetFileState(CRSSBriefData::EDocListFileDone);
		doc->SetUpdate(ETrue);
		iDocListEngine->Save(*docList);
		}
	UpdateDownloadListView();
	}

void CEngineManager::HandleDownloadEvent(CQWString& filename, QINT aEvent,
		void* aData)
	{
	}

void CEngineManager::HandleGetLinkEvent(CQWString& filename, QINT chapterId,
		QINT aEvent, void* aData)
	{
	}

CDownloadInfoData* CEngineManager::GetTaskByName(CQWString& filename)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();

	TPtrC title;
	title.Set((const TUint16*) (filename.GetDataPtr()),
			filename.GetLength());
	TInt pos = title.LocateReverse('\\');
	title.Set(title.Mid(pos + 1));
	title.Set(title.Left(title.Length() - 3));
	
	for (int i = list->Count() - 1; i >= 0; i--)
		{
		CDownloadInfoData* info = (*list)[i];

		if (!info)
			continue;

		if (info->GetFile()->Des().Left(info->GetFile()->Length() - 3).Compare(title) == 0)
			{
			return info;
			}
		}
	return NULL;
	}

TInt CEngineManager::GetTaskIndexByName(CQWString& filename)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();

	for (int i = list->Count() - 1; i >= 0; i--)
		{
		CDownloadInfoData* info = (*list)[i];

		if (!info)
			continue;

		TPtrC title;
		title.Set((const TUint16*) (filename.GetDataPtr()),
				filename.GetLength());
		TInt pos = title.LocateReverse('\\');
		title.Set(title.Mid(pos + 1));
		title.Set(title.Left(title.Length() - 3));

		if (info->GetFile()->Des().Left(info->GetFile()->Length() - 3).Compare(title) == 0)
			{
			return i;
			}
		}
	return KErrNotFound;
	}

CRSSBriefData* CEngineManager::GetDocByName(CQWString& filename)
	{
	ArrayDocList* list = SHModel()->GetDocList();

	TPtrC title;
	title.Set((const TUint16*) (filename.GetDataPtr()),
			filename.GetLength());
	TInt pos = title.LocateReverse('\\');
	title.Set(title.Mid(pos + 1));
			
	for (int i = list->Count() - 1; i >= 0; i--)
		{
		CRSSBriefData* doc = (*list)[i];

		if (!doc)
			continue;

		if (doc->GetMp3File()->Des().Compare(title) == 0)
			{
			return doc;
			}
		}
	return NULL;	
	}

TInt CEngineManager::GetDocIndexByName(CQWString& filename)
	{
	ArrayDocList* list = SHModel()->GetDocList();
	TPtrC title;
	title.Set((const TUint16*) (filename.GetDataPtr()),
			filename.GetLength());
	TInt pos = title.LocateReverse('\\');
	title.Set(title.Mid(pos + 1));
			
	for (int i = list->Count() - 1; i >= 0; i--)
		{
		CRSSBriefData* doc = (*list)[i];

		if (!doc)
			continue;

		if (doc->GetMp3File()->Des().Compare(title) == 0)
			{
			return i;
			}
		}
	return KErrNotFound;	
	}

CRSSBriefData* CEngineManager::GetDocByUrl(CQWString& filename)
	{
	ArrayDocList* list = SHModel()->GetDocList();

	TPtrC title;
	title.Set((const TUint16*) (filename.GetDataPtr()),
			filename.GetLength());
			
	for (int i = list->Count() - 1; i >= 0; i--)
		{
		CRSSBriefData* doc = (*list)[i];

		if (!doc)
			continue;

		if (doc->GetMp3Url()->Des().Compare(title) == 0)
			{
			return doc;
			}
		}
	return NULL;	
	}

TInt CEngineManager::GetDocIndexByUrl(CQWString& filename)
	{
	ArrayDocList* list = SHModel()->GetDocList();
	TPtrC title;
	title.Set((const TUint16*) (filename.GetDataPtr()),
			filename.GetLength());
			
	for (int i = list->Count() - 1; i >= 0; i--)
		{
		CRSSBriefData* doc = (*list)[i];

		if (!doc)
			continue;

		if (doc->GetMp3Url()->Des().Compare(title) == 0)
			{
			return i;
			}
		}
	return KErrNotFound;	
	}

void CEngineManager::UpdateDownloadListView()
	{
	if (iDownloadProcessNotify)
		{
		ArrayDownloadList* list = SHModel()->GetDownloadList();
		CDesCArray * array = iDownloadProcessNotify->GetList();
		iDownloadEngine->ConvertToListFormat(*list, array);
		iDownloadProcessNotify->UpdateDownloadProcessList();
		}
	}

void CEngineManager::NotifyProgress(CQWString& filename, QINT aReceived,
		QINT aTotalSize, float per)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();
	CDownloadInfoData* info = GetTaskByName(filename);
	if (info)
		{
		int progress = float(per * 10);
		info->SetProgress(progress);
		info->SetUpdate(ETrue);
		iDownloadEngine->Save(*list);
		}
	UpdateDownloadListView();
	}

void CEngineManager::NotifyProgress(CQWString& filename, QINT aReceived)
	{
	}

void CEngineManager::NotifyAddDownTask(CQWString& filename, CQWString& url,
		QINT aStatus)
	{
	switch (aStatus)
		{
		case download_task_finish:
			AfterTaskDone(filename,url);
			break;
		case download_task_downing:
		case download_task_pause:
		case download_task_waiting:
			ChangeTaskStatus(filename,aStatus);
			break;
		}
	}
void CEngineManager::NotifyLaunchTask()
	{
	}
void CEngineManager::NotifyDownLimit()
	{
	}

void CEngineManager::LoadAllToDownloadList(CDesCArray* aDesC)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();
	list->ResetAndDestroy();
	iDownloadEngine->GetAll(*list);
	iDownloadEngine->ConvertToListFormat(*list, aDesC);
	}

void CEngineManager::UpdateToDownloadList(CDesCArray* aDesC)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();
	iDownloadEngine->ConvertToListFormat(*list, aDesC);
	}

TInt CEngineManager::ConvertToDownloadListIndex(const TInt& aPos)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();
	TInt count = list->Count();
	TInt index = -1;
	if (aPos >= 0 && count > aPos)
		index = count - 1 - aPos;
	return index;
	}

void CEngineManager::StartTask(const TInt& aPos)
	{
	TInt index = ConvertToDownloadListIndex(aPos);
	if (index >= 0)
		{
		ArrayDownloadList* list = SHModel()->GetDownloadList();
		iDownloadEngine->StartTask(*list, index);
		}
	}

void CEngineManager::StartTaskAll(CDesCArray* aDesC)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();
	iDownloadEngine->StartAll(*list);
	aDesC->Reset();
	iDownloadEngine->ConvertToListFormat(*list,aDesC);
	}

void CEngineManager::StopTaskAll(CDesCArray* aDesC)
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();
	iDownloadEngine->PauseAll(*list);
	aDesC->Reset();
	iDownloadEngine->ConvertToListFormat(*list,aDesC);
	}

void CEngineManager::StartTask(const TInt& aPos, CDesCArray* aDesC)
	{
	TInt index = ConvertToDownloadListIndex(aPos);
	if (index >= 0)
		{
		ArrayDownloadList* list = SHModel()->GetDownloadList();
		iDownloadEngine->StartTask(*list, index);
		iDownloadEngine->ConvertToListFormat(*list, aDesC);
		}
	}

void CEngineManager::StopTask(const TInt& aPos, CDesCArray* aDesC)
	{
	TInt index = ConvertToDownloadListIndex(aPos);
	if (index >= 0)
		{
		ArrayDownloadList* list = SHModel()->GetDownloadList();
		iDownloadEngine->PauseTask(*list, index);
		iDownloadEngine->ConvertToListFormat(*list, aDesC);
		}
	}

TBool CEngineManager::IsTaskRunning(const TInt& aPos)
	{
	TInt index = ConvertToDownloadListIndex(aPos);
	if (index >= 0)
		{
		ArrayDownloadList* list = SHModel()->GetDownloadList();
		iDownloadEngine->IsTaskRunningOrWaiting(*list, aPos);
		}
	}

void CEngineManager::RemoveTask(const TInt& aPos, CDesCArray* aDesC)
	{
	TInt index = ConvertToDownloadListIndex(aPos);
	if (index >= 0)
		{
		ArrayDownloadList* list = SHModel()->GetDownloadList();
		iDownloadEngine->RemoveTask(*list, index);
		iDownloadEngine->ConvertToListFormat(*list, aDesC);
		}
	}

void CEngineManager::ClearAll()
	{
	ArrayDownloadList* list = SHModel()->GetDownloadList();
	iDownloadEngine->ClearAll(*list);

	ArrayDocList* docList = SHModel()->GetDocList();
	iDocListEngine->ClearAll(*docList);
	
	cx_sendmessage(EMessage_BookLib_Download_RemoveAllDownloadInfoList,0,0,EModule_Controller_BookLibrary,-1);
			
	}
